#include "threadpool.h"
#include "tpthread.h"
#include <thread>

void *
PThread::entry(void *data, int id)
{
    PThread *trd = (PThread *)data;
    {
        std::lock_guard<std::mutex> locker(trd->_mutex);
    }

    if (trd->_func)
    {
        trd->_func(trd->_data, id);
    }

    std::lock_guard<std::mutex> locker(trd->_mutex);
    trd->_cv.notify_one();
    trd->_posted = true;

    return NULL;
}

PThread::PThread()
{
    _func   = NULL;
    _data   = NULL;
    _id     = -1;
    _active = false;
    _posted = false;
}

PThread::~PThread()
{
}

void
PThread::setEntry(THREADENTRY func, void * data, int id)
{
    _func = func;
    _data = data;
    _id   = id;
}

int
PThread::start()
{
    std::lock_guard<std::mutex> locker(_mutex);

    if (tpool->launch(entry, this, _id) < 0)
    {
        return -1;
    }
    _active = true;

    return 0;
}

void
PThread::stop()
{
    std::unique_lock<std::mutex> lock(_mutex);
    if (!_active)
    {
        return;
    }

    _active = false;

    while (!_posted)
    {
        _cv.wait(lock);
    }
}

bool
PThread::active()
{
    std::lock_guard<std::mutex> locker(_mutex);
    return _active;
}
